package org.p2psimulator.entity.behavior;

import java.util.Random;

import org.p2psimulator.config.BehaviorConfig;
import org.p2psimulator.entity.Id;
import org.p2psimulator.entity.Message;
import org.p2psimulator.entity.protocol.messages.general.DownloadRequestMessage;
import org.p2psimulator.entity.reputation.Reputation;
import org.p2psimulator.entity.reputation.ReputationRepository;

public class DisturbingBehavior extends Behavior {

    private double disturbingInteracionCount = 0;
    private static Random r = new Random();

    @Override
    public boolean answareMessage(Id rater, Message msg) {

        interacitonCount++;
        if (msg instanceof DownloadRequestMessage && msg.getOriginBehavior() != BehaviorTypes.SELFISH) {
            disturbingInteracionCount++;
        }
        if (checkDisturbingRateCondition(thisReputation)) {
            int f = r.nextInt(101);
            if (f < 60) {
                return true;
            } else {
                return false;
            }
        } else {
            return true;
        }
    }

    @Override
    public BehaviorTypes getBehaviorType() {
        return BehaviorTypes.DISTURBING;
    }

    @Override
    public double ratePeer(Id rater, Id ratee,
            BehaviorTypes rateeBehavior,
            ReputationRepository repository) {
        updateReputation(rater, repository);
        
        boolean positive = false;
        try {
            Reputation reputation = repository.getLocalReputation(rater,
                    ratee);
            if (reputation != null) {
                positive = reputation.getNormalReputation() > 0;
            } else {
                positive = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        if (checkDisturbingRateCondition(thisReputation)) {
            return positive ? -1 : 1;
        } else {
            return positive ? 1 : -1;
        }
    }

    @Override
    public double rateResource(Id rater, Id resource,
            ReputationRepository repository) {

        updateReputation(rater, repository);
        boolean positive = false;
        try {
            Reputation reputation = repository.getLocalReputation(rater,
                    resource);
            if (reputation != null) {
                positive = reputation.getNormalReputation() > 0;
            } else {
                positive = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        if (checkDisturbingRateCondition(thisReputation)) {
            return positive ? -1 : 1;
        } else {
            return positive ? 1 : -1;
        }
    }

    @Override
    public double rateTransaction(Id rater, Id ratee, int transResult,
            BehaviorTypes rateeBehavior,
            ReputationRepository repository) {

        interacitonCount++;
        updateReputation(rater, repository);
        boolean positive = false;
        try {
            positive = transResult>=0;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
        if (checkDisturbingRateCondition(thisReputation)) {
            return positive ? -1 : 1;
        } else {
            return positive ? 1 : -1;
        }
    }
    private boolean disturbing = false;

    private boolean checkDisturbingRateCondition(double avg) {


        if (avg >= BehaviorConfig.disturbingrate
                && disturbingInteracionCount > BehaviorConfig.disturbingInteractions && !disturbing) {
            disturbing = true;
        }
        return disturbing;

    }

    @Override
    public boolean leaveNetwork() {
        boolean ret = false;

        if (thisReputation < BehaviorConfig.leavingrate
                && disturbingInteracionCount > BehaviorConfig.disturbingInteractions
                && disturbing) {
            ret = true;
            disturbingInteracionCount = 0;
            disturbing = false;
        } else {
            ret = false;
        }
        return ret;
    }

    @Override
    public boolean damageResource() {
        return disturbing;
    }

    @Override
    public boolean rate() {
        return true;
    }

    @Override
    public boolean transacNeutro(BehaviorTypes rateeBehavior, Id ratee) {
        return false;
    }

    public void incInteractions() {
        disturbingInteracionCount++;
    }
}
